package HTTP

import (
	"emb/emb_server/SQL/util"
	"emb/emb_server/logs"
	"net/http"
)

//发送消息：
//s userID  string,talkerID string,msgContent string
//r Message string

func sendMessage(w http.ResponseWriter, r *http.Request) {

	code := Success
	info := "success"
	var information interface{}

	defer func() {
		writeResult(w, code, info, information)
	}()

	config(w, r)

	err := r.ParseForm()
	if err != nil {
		logs.Print("From:sendMessage:---参数解析失败！请使用x-www-form-urlencoded格式传输参数数据！")
		info = "参数解析失败！请使用x-www-form-urlencoded格式传输参数数据！"
		code = errParseForm
		return
	}

	sender := r.Form["userID"]
	receiver := r.Form["talkerID"]
	content := r.Form["msgContent"]

	if sender == nil {
		code = errEmptyParameter
		logs.Print("From:sendMessage:---userID is null")
		info = "From:sendMessage:---userID is null"
		return
	}
	if receiver == nil {
		code = errEmptyParameter
		logs.Print("From:sendMessage:---talkerID is null")
		info = "From:sendMessage:---talkerID is null"
		return
	}
	if content == nil {
		code = errEmptyParameter
		logs.Print("From:sendMessage:---msgContent is null")
		info = "From:sendMessage:---msgContent is null"
		return
	}
	info, code, ok := checkOutInsertMessage(sender[0], receiver[0], content[0])
	if !ok {
		return
	}

	ok, code, info = insertMessages(sender[0], receiver[0], content[0])
	if !ok {
		return
	}
}

//插入messages 表 数据
func insertMessages(sender string, receiver string, content string) (bool, int, string) {
	info := "success"
	sql := "insert into messages(content,sender,receiver) values ($1,$2,$3)"
	code := Success

	info, code, ok := checkOutInsertMessage(sender, receiver, content)
	if !ok {
		return false, code, info
	}

	db := util.GetDb()
	stmt, err := db.Prepare(sql)
	defer stmt.Close()
	if err != nil {
		logs.Print("From:sendMessage.Prepare")
		info = "From:sendMessage.Prepare---error"
		return false, errDBExecFailed, info
	}

	_, err = stmt.Exec(content, sender, receiver)
	if err != nil {
		logs.Print("From:sendMessage.Exec", err.Error())
		info = "From:sendMessage.Exec---error"
		return false, errDBExecFailed, info
	}

	return true, code, info
}

func checkOutInsertMessage(userID string, talkerID string, magContent string) (string, int, bool) {

	info := "success"

	if ok, code, info := checkOutId(userID); !ok {
		info = "userID is Invalid"
		return info, code, false
	}

	if ok, code, info := checkOutId(talkerID); !ok {
		info = "talkerID is Invalid"
		return info, code, false
	}

	if magContent == "" {
		info = "msgContent is empty"
		return info, errInvalidMsgContent, false
	}

	if userID == talkerID {
		info = "userID is the same as talkerID"
		return info, errInvalidID, false

	}

	if info, _, ok := queryObject(userID); !ok {
		info = "userID is no exits"
		return info, errInvalidID, false
	}

	if info, _, ok := queryObject(talkerID); !ok {
		info = "talkerID is no exits"
		return info, errInvalidID, false
	}

	if _, _, ok := isGroup(userID); ok {
		info = "userID is Invalid because userID is groupID"
		return info, errInvalidID, false
	}

	if _, _, ok := isGroup(talkerID); ok {
		if info, code, ok := isGroupMember(userID, talkerID); !ok {
			return info, code, ok
		}
	}

	return info, Success, true
}

func isGroupMember(userID string, groupID string) (string, int, bool) {

	info := "success"
	code := Success
	sql := "select userid from members where groupid = $1"

	db := util.GetDb()

	stmt, err := db.Prepare(sql)
	defer stmt.Close()
	if err != nil {
		logs.Print("From:sendMessage.isGroupMember.Prepare")
		info = "From:sendMessage.isGroupMember.Prepare---error"
		return info, errDBQueryFailed, false
	}
	rows, err := stmt.Query(groupID)
	defer rows.Close()
	if err != nil {
		if err != nil {
			logs.Print("From:sendMessage.isGroupMember.Query")
			info = "From:sendMessage.isGroupMember.Query---error"
			return info, errDBQueryFailed, false
		}
	}
	var memberID string
	for rows.Next() {
		err = rows.Scan(&memberID)
		if err != nil {
			logs.Print("From:sendMessage.isGroupMember.Scan")
			info = "From:sendMessage.isGroupMember.Scan---error"
			return info, errRowsScan, false
		}
		if memberID == userID {
			return info, code, true
		}
	}
	info = "userID is not the talkerID group member"
	return info, errInvalidID, false
}

func isGroup(id string) (string, int, bool) {
	info := "success"
	code := Success
	sql := "select isuser from objects where id = $1"
	db := util.GetDb()
	stmt, err := db.Prepare(sql)
	defer stmt.Close()
	if err != nil {
		logs.Print("From:sendMessage.isGroup.Prepare")
		info = "From:sendMessage.isGroup.Prepare---error"
		return info, errDBQueryFailed, false
	}
	rows, err := stmt.Query(id)
	defer rows.Close()
	if err != nil {
		if err != nil {
			logs.Print("From:sendMessage.isGroup.Query")
			info = "From:sendMessage.isGroup.Query---error"
			return info, errDBQueryFailed, false
		}
	}
	var isUser bool
	for rows.Next() {
		err = rows.Scan(&isUser)
		if err != nil {
			logs.Print("From:sendMessage.isGroup.Scan")
			info = "From:sendMessage.isGroup.Scan---error"
			return info, errRowsScan, false
		}
		if isUser {
			return info, code, false
		} else {
			return info, code, true
		}
	}

	return info, code, true
}
